<?php

namespace SC\Venus\Controllers;

use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;


class VenusController extends Controller
{
    protected static $controllerNames = [];
    protected static $enableCategory = false;
    protected static $enableTags = false;

    public static function name()
    {
        $name = static::$controllerNames[static::class] ?? null;
        if (!$name) {
            $strs = explode('\\', static::class);
            $clsName = $strs[count($strs) - 1];
            $name = str_replace('Controller', '', $clsName);
            static::$controllerNames[static::class] = $name;
        }
        return $name;
    }

    public static function navOrder()
    {
        return 50;
    }

    public static function perPage()
    {
        return 10;
    }

    public static function registerRoute($router)
    {
        $router->resource(static::uriName(), static::class);
    }

    public static function registerNavigation($navigation)
    {
        $navigation->addNavItem(static::name(), route('venus.'.static::uriName().'.index'), static::navOrder());
        $navigation->addCreationNavItem(static::name(), route('venus.'.static::uriName().'.create'), static::navOrder());
    }

    public static function uriName()
    {
        return Str::plural(Str::kebab(static::name()));
    }

    public static function model()
    {
        return 'App\\' . static::name();
    }

    protected function indexView()
    {
        return 'venus.' . static::uriName() . '.index';
    }

    protected function formView($id=null)
    {
        return 'venus.' . static::uriName() . '.form';
    }

    protected function showView()
    {
        return 'venus.' . static::uriName() . '.show';
    }

    protected function indexQuery($query)
    {
        if (static::$enableCategory) {
            $query = $query->with('category');
        }
        return $query;
    }

    protected function showQuery($query)
    {
        if (static::$enableCategory) {
            $query = $query->with('category');
        }
        return $query;
    }

    protected function editQuery($query)
    {
        return $query;
    }

    protected function indexContext()
    {
        $query = static::model()::where([]);

        if ($queryStr = request()->query('q')) {
            if(is_numeric($queryStr)) {
                $query->where('id', (int)$queryStr);
            } else {
                $query->whereRaw($queryStr);
            }
        }
        $this->indexQuery($query);
        $resultSet = $query->orderBy('id', 'desc')->paginate(request()->query('num', static::perPage()));
        return [
            'payload' => $resultSet->items(),
            'pagination' => $resultSet,
            'breadcrumb' => [
                [static::uriName(),],
            ],
        ];
    }

    protected function showPayload($payload)
    {
        if (static::$enableTags) {
            $payload->append('tag_names');
        }
        return $payload;
    }

    protected function formPayload($payload)
    {
        if (static::$enableTags) {
            $payload->append('tag_names');
        }
        return $payload;
    }

    protected function showContext($id)
    {
        $query = static::model()::where([]);
        $this->showQuery($query);
        return [
            'payload' => $this->showPayload($query->findOrFail($id)),
            'breadcrumb' => [
                [static::uriName(), route('venus.' . static::uriName() . '.index'),],
                ["show(${id})",],
            ],
        ];
    }

    protected function formContext($id=null)
    {
        $ctx = [];
        if (static::$enableCategory) {
            $ctx['categories'] = \App\Category::select(['id', 'name'])->get()->map(function($item) {
                return ['id' => $item->id, 'name' => $item->name];
            });
        }
        if ($id) {
            $query = static::model()::where([]);
            $this->editQuery($query);
            $ctx['breadcrumb'] = [
                [static::uriName(), route('venus.' . static::uriName() . '.index'),],
                ["edit(${id})"],
            ];
            $ctx['payload'] = $this->formPayload($query->findOrFail($id));
        } else {
            $ctx['breadcrumb'] = [
                [static::uriName(), route('venus.' . static::uriName() . '.index'),],
                ['create',],
            ];
        }

        return $ctx;
    }

    protected function formSubmit($id, $input)
    {
        $tagNames = $input['tag_names'] ?? null;
        unset($input['tag_names']);

        if ($id) {
            if (!empty($input)) {
                static::model()::where('id', $id)->update($input);
            }
        } else {
            $inst = static::model()::create($input);
            $id = $inst->id;
        }

        if(static::$enableTags && !is_null($tagNames)) {
            $inst = static::model()::find($id);
            $inst->setTagNames($tagNames);
        }

        return ['id' => $id];
    }

    public function index()
    {
        return view($this->indexView(), $this->indexContext());
    }

    public function show($id)
    {
        return view($this->showView(), $this->showContext($id));
    }

    public function create()
    {
        return view($this->formView(), $this->formContext());
    }

    public function edit($id)
    {
        return view($this->formView(), $this->formContext($id));
    }

    public function store()
    {
        return response()->json($this->formSubmit(null, request()->input()));
    }

    public function update($id)
    {
        return response()->json($this->formSubmit($id, request()->input()));
    }

    public function destroy($id)
    {
        static::model()::destroy($id);
        return response()->json([
            'id' => $id,
        ]);
    }
}